package com.rocsun;

import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.config.querys.MySqlQuery;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.DbColumnType;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import com.baomidou.mybatisplus.generator.query.SQLQuery;
import org.springframework.boot.test.context.SpringBootTest;

import java.sql.Types;
import java.util.Map;

/**
 * @program: rocsun-scali
 * @description:
 * @author: yx.guo
 * @create: 2025-10-18 23:01
 **/
@SpringBootTest
public class MybatisGenerator {

    private static final String url = "jdbc:mysql://localhost:3306/rocsun?useUnicode=true&characterEncoding=UTF-8";
    private static final String username = "root";
    private static final String password = "Rocsun19931211.";
    private static final String userDir = System.getProperty("user.dir");
    public static final String AUTHOR = "rocsun";

    public static void main(String[] args) {
        FastAutoGenerator.create(url, username, password)
                // 1. 全局配置
                .globalConfig(builder -> {
                    builder.author(AUTHOR) // 作者名
                            .disableOpenDir() // 生成后不自动打开文件夹
                            .commentDate("yyyy-MM-dd HH:mm:ss") // 注释日期格式
                            // 日期类型字段的映射（数据库datetime -> 实体类LocalDateTime）
                            .dateType(DateType.TIME_PACK)
                            // 开启Swagger2注解（需引入Swagger依赖，生成@Api等注解）
                            .enableSwagger()
                            .build();
                })
                // 2. 数据源配置（指定数据库类型、连接信息）
                .dataSourceConfig(builder ->
                        builder.databaseQueryClass(SQLQuery.class)
                                .dbQuery(new MySqlQuery())
                                .typeConvertHandler((globalConfig, typeRegistry, metaInfo) -> {
                            int typeCode = metaInfo.getJdbcType().TYPE_CODE;
                            if (typeCode == Types.SMALLINT) {
                                // 自定义类型转换
                                return DbColumnType.INTEGER;
                            }
                            return typeRegistry.getColumnType(metaInfo);
                        })
                )
                // 3. 包配置（生成的类放在哪个包下）
                .packageConfig(builder ->
                        builder
                                .parent("") // 设置父包名
//                                .moduleName("dal") // 设置父包模块名
                                .entity("com.rocsun.entity") // 实体类包名（默认entity）
                                .mapper("com.rocsun.mapper") // Mapper接口包名（默认mapper）
                                .service("com.rocsun.repository") // Service接口包名（默认service）
                                .serviceImpl("com.rocsun.repository.impl") // Service实现类包名（默认service.impl）
//                                .controller("controller") // Controller包名（默认controller）
                                .xml("mapper") // Mapper.xml文件存放路径（默认mapper/xml）
                                // 为Mapper.xml单独指定输出目录（通常在src/main/resources）
                                // 关键：为每个组件指定对应模块的输出目录
                                .pathInfo(Map.of(
                                        OutputFile.entity,        // 实体类输出到dal模块的java目录
                                        userDir + "/dal/src/main/java/com/rocsun/entity",

                                        OutputFile.mapper,        // Mapper接口输出到dal模块的java目录
                                        userDir + "/dal/src/main/java/com/rocsun/mapper",

                                        OutputFile.xml,    // XML输出到dal模块的resources目录
                                        userDir + "/dal/src/main/resources/mapper",

                                        OutputFile.service,       // Service接口输出到service模块的java目录
                                        userDir + "/dal/src/main/java/com/rocsun/repository",

                                        OutputFile.serviceImpl,  // Service实现类输出到service模块的java目录
                                        userDir + "/dal/src/main/java/com/rocsun/repository/impl"
                                ))
                                .build()
                )
                // 4. 策略配置（表、字段的生成策略）
                .strategyConfig(builder -> builder
                                // 1. 指定生成的表（必选）：支持单个表、多个表、通配符（如"user_*"）
                                .addInclude("user") // 要生成的表名
//                                .addExclude("t_log") // 排除不需要生成的表（可选）
                                //.likeTable(new LikeTable("t_", SqlLike.LEFT)) // 按前缀匹配表（如匹配所有t_开头的表）

//                                // 3. 实体类策略
                                .entityBuilder()
                                .enableFileOverride()
                                .enableColumnConstant()
                                .enableLombok() // 开启Lombok：实体类生成@Data、@EqualsAndHashCode等注解
                                .enableSerialAnnotation() //
                                .enableTableFieldAnnotation() // 为实体类字段添加@TableField注解（默认仅特殊字段生成）
                                .logicDeleteColumnName("deleted") // 逻辑删除字段名（生成@TableLogic注解）
                                .versionColumnName("version") // 乐观锁字段名（生成@Version注解）
                                .formatFileName("%sDO") // 实体类文件名格式（默认是表名转驼峰，这里加"Entity"后缀）

                                // 4. Controller策略
                                .controllerBuilder()
                                .disable()
//                                .enableFileOverride()
//                                .enableRestStyle() // 生成@RestController（REST风格）
//                                .enableHyphenStyle() // 接口路径驼峰转连字符（如UserController→/user/**）
//                                .formatFileName("%sController") // Controller文件名格式

                                // 5. Service策略
                                .serviceBuilder()
                                .enableFileOverride()
                                .formatServiceFileName("%sRepository") // Service接口名格式（默认I%sService，这里去掉I前缀）
                                .formatServiceImplFileName("%sRepositoryImpl") // Service实现类名格式

                                // 6. Mapper策略
                                .mapperBuilder()
                                .enableFileOverride()
                                .formatMapperFileName("%sDAO") // Mapper接口名格式
                                .formatXmlFileName("%sMapper") // Mapper.xml文件名格式
                )
                .templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板，默认的是Velocity引擎模板
                .execute();
    }

}
